#include "UserLogin.h"
#include "Message.h"
#include "Mylogger.h"

#include <shadow.h>
#include <iostream>
#include <string.h>

using std::cout;
using std::endl;

namespace SOS
{

void UserLoginSection1::process()
{
    cout << "loign section1 is processing" << endl;
    
    if(_packet.type == SOS::TASK_TYPE_LOGIN_SECTION1)
    {
        string username = _packet.msg;
        //spwd 是 Linux 系统中用于存储影子密码文件（/etc/shadow）中用户信息的结构体
        struct spwd * sp;
        sp = getspnam(username.c_str());
        if(sp == nullptr)
        {
            LogDebug("getspnam error");
        
            SOS::TLV tlv;
            tlv.type = SOS::TASK_TYPE_LOGIN_SECTION1_RESP_ERROR;
            tlv.length = 0;
            _conn->sendInLoop(tlv);
            return;
        }

        string setting;
        getSetting(setting, sp->sp_pwdp);
        LogDebug("setting : %s\n", setting.c_str());

        SOS::TLV tlv;
        tlv.type = SOS::TASK_TYPE_LOGIN_SECTION1_RESP_OK;
        tlv.length = setting.length();
        strncpy(tlv.data, setting.c_str(), tlv.length);
        _conn->sendInLoop(tlv);
    }
}

void UserLoginSection1::getSetting(string & s, const char * passwd)
{
    int i,j;
    for(i = 0, j = 0; passwd[i] && j!= 4; ++i)
    {
        if(passwd[i] == '$')
        {
            j++;
        }
    }
    char buff[128] = {0};
    strncpy(buff, passwd, i);
    s.assign(buff, i);
}

void UserLoginSection2::process()
{
    cout << "login section2 is processing" << endl;
    if (_packet.type == SOS::TASK_TYPE_LOGIN_SECTION2) {
        string content = _packet.msg;
        size_t colonPos = content.find(':');
        if (colonPos == string::npos) {
            SOS::TLV tlv;
            tlv.type = SOS::TASK_TYPE_LOGIN_SECTION2_RESP_ERROR;
            tlv.length = 0;
            _conn->sendInLoop(tlv);
            return;
        }
        string username = content.substr(0, colonPos);
        string encryptedPwd = content.substr(colonPos + 1);

        // 查询用户密文
        struct spwd* sp = getspnam(username.c_str());
        if (sp == nullptr) {
            SOS::TLV tlv;
            tlv.type = SOS::TASK_TYPE_LOGIN_SECTION2_RESP_ERROR;
            tlv.length = 0;
            _conn->sendInLoop(tlv);
            return;
        }

        // 验证加密密码是否与存储的密文一致
        char* result = crypt(encryptedPwd.c_str(), sp->sp_pwdp);
        if (result != nullptr && strcmp(result, sp->sp_pwdp) == 0) {
            SOS::TLV tlv;
            tlv.type = SOS::TASK_TYPE_LOGIN_SECTION2_RESP_OK;
            tlv.length = 0;
            _conn->sendInLoop(tlv);
        } else {
            SOS::TLV tlv;
            tlv.type = SOS::TASK_TYPE_LOGIN_SECTION2_RESP_ERROR;
            tlv.length = 0;
            _conn->sendInLoop(tlv);
        }
    }
}

}//end of namespace SOS
